/******************************************************************************
* Copyright (C) 2010-2011 Computer Graphics Systems Group at the 
* Hasso-Plattner-Institute (HPI), Potsdam, Germany.
*
* Lecture : Geovisualisation Summer Term 2011
* Exercise: Processing Rendering OpenStreetMap Data 
*
* Author: sebastian.pasewaldt@hpi.uni-potsdam.de
*
******************************************************************************/

#ifndef __OSMHANDLER_H__
#define __OSMHANDLER_H__


//[-------------------------------------------------------]
//[ Includes                                              ]
//[-------------------------------------------------------]

#include <QtXml/QXmlDefaultHandler>
#include <QtCore/QPair>
#include <QMap>
#include <vector>

class OSMNode;
class OSMWay;
class OSMRelation;

//[-------------------------------------------------------]
//[ Classes                                               ]
//[-------------------------------------------------------]
/**
*  @brief
*    OSG viewer for Qt
*/
class OSMHandler: public QXmlDefaultHandler
{
    //[-------------------------------------------------------]
    //[ Public functions                                      ]
    //[-------------------------------------------------------]
    public:
		/**
		*  @brief
		*    Constructor
		*/
        OSMHandler();
		
		~OSMHandler();

		/**
		*  @brief
		*    is called when parsing of a new document has started
		*/
		bool startDocument();
		
		/**
		*  @brief
		*    is called when parsing of the document has finished
		*/
		bool endDocument();

		/**
		*  @brief
		*    is called every time a new element has been recognized
		*  @param namespaceURI
		*    namespace for qualified names
		*  @param localName
		*    (unqualified) name of the element
		*  @param qName
		*    qualified name of the element
		*  @param atts
		*    list of key-value pairs of all attributes belonging to the element
		*/
		bool startElement(const QString& namespaceURI, const QString& localName
			, const QString& qName, const QXmlAttributes& atts);
		
		/**
		*  @brief
		*    is called after the element has been processed
		*  @param namespaceURI
		*    namespace for qualified names
		*  @param localName
		*    (unqualified) name of the element
		*  @param qName
		*    qualified name of the element
		*/
		bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName);



    //[-------------------------------------------------------]
    //[ Private functions                                     ]
    //[-------------------------------------------------------]
    private:
        bool parseOSMNode(const QXmlAttributes& atts);
        bool parseOSMWay(const QXmlAttributes& atts);
        bool parseOSMRelation(const QXmlAttributes& atts);

        bool parseOSMNodeTag(const QXmlAttributes& atts);
        bool parseOSMWayPoint(const QXmlAttributes& atts);
        bool parseOSMWayTag(const QXmlAttributes& atts);
        bool parseOSMRelationMember(const QXmlAttributes& atts);
        bool parseOSMRelationTag(const QXmlAttributes& atts);

    //[-------------------------------------------------------]
    //[ Private data                                          ]
    //[-------------------------------------------------------]
    private:
        enum ParseState
        {
            UNDEFINED,
            NODE,
            WAY,
            RELATION,
        };

        ParseState m_state;

    public:
        std::vector<OSMNode> m_osmNodes;
        std::vector<OSMWay> m_osmWays;
        std::vector<OSMRelation> m_osmRelations;
};

#endif // __OSMHANDLER_H__